package vn.vfriends.soffice.bean;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.inject.Inject;
import org.apache.commons.codec.digest.DigestUtils;
import org.omnifaces.util.Faces;
import org.primefaces.context.RequestContext;
import org.primefaces.model.DualListModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import vn.vfriends.soffice.entity.Dept;
import vn.vfriends.soffice.entity.Group;
import vn.vfriends.soffice.entity.User;
import vn.vfriends.soffice.service.DeptService;
import vn.vfriends.soffice.service.GroupService;
import vn.vfriends.soffice.service.UserService;

/**
 *
 * @author chaungoctuan@gmail.com
 */
@ManagedBean
@ViewScoped
public class UserBean implements Serializable {

    private static final Logger logger = LoggerFactory.getLogger(UserBean.class);
    
    @Inject private UserService userService;
    
    @Inject private DeptService deptService;
    
    @Inject private GroupService groupService;
    
    private User[] selectedUsers;
    private User user;
    
    private Integer userId;
    
    private DualListModel<Group> groupModels;

    public Integer getUserId() {
        return userId;
    }

    public void setUserId(Integer userId) {
        this.userId = userId;
    }

    public User[] getSelectedUsers() {
        return selectedUsers;
    }

    public void setSelectedUsers(User[] selectedUsers) {
        this.selectedUsers = selectedUsers;
    }

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    public List<User> getUserList() {
        return this.userService.findAll();
    }
    
    public List<Dept> getDeptList() {
        return this.deptService.findAll();
    }

    public DualListModel<Group> getGroupModels() {
        return groupModels;
    }

    public void setGroupModels(DualListModel<Group> groupModels) {
        this.groupModels = groupModels;
    }
    
    public void preViewAction() {
        try {
            if(this.user != null){
                Map<String,List<String>> params = new HashMap<String, List<String>>();
                params.put("userId", Arrays.asList(this.user.getId().toString()));
                RequestContext.getCurrentInstance().openDialog("view", null, params);
            } else if (this.selectedUsers == null || this.selectedUsers.length == 0) {
                FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, "Thông báo", "Hãy chọn một người dùng");
                RequestContext.getCurrentInstance().showMessageInDialog(message);
            } else if (this.selectedUsers.length > 1) {
                FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, "Thông báo", "Chỉ chọn một người dùng");
                RequestContext.getCurrentInstance().showMessageInDialog(message);
            } else {
                this.user = this.selectedUsers[0];
                Map<String,List<String>> params = new HashMap<String, List<String>>();
                params.put("userId", Arrays.asList(this.user.getId().toString()));
                RequestContext.getCurrentInstance().openDialog("view", null, params);
            }
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Thông báo", "Lỗi hệ thống");
            RequestContext.getCurrentInstance().showMessageInDialog(message);
        }
    }
    
    public void preRenderDetailView() {
        this.user = this.userService.find(userId);
        if (this.user == null) {
            FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Thông báo", "Người dùng không tồn tại");
            Faces.getContext().addMessage(null, message);
        }
    }
    
    public void preEditAction() {
        try {
            if(this.user != null){
                Map<String,List<String>> params = new HashMap<String, List<String>>();
                params.put("userId", Arrays.asList(this.user.getId().toString()));
                RequestContext.getCurrentInstance().openDialog("edit", null, params);
            } else if (this.selectedUsers == null || this.selectedUsers.length == 0) {
                FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, "Thông báo", "Hãy chọn một người dùng");
                RequestContext.getCurrentInstance().showMessageInDialog(message);
            } else if (this.selectedUsers.length > 1) {
                FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, "Thông báo", "Chỉ chọn một người dùng");
                RequestContext.getCurrentInstance().showMessageInDialog(message);
            } else {
                this.user = this.selectedUsers[0];
                Map<String,List<String>> params = new HashMap<String, List<String>>();
                params.put("userId", Arrays.asList(this.user.getId().toString()));
                RequestContext.getCurrentInstance().openDialog("edit", null, params);
            }
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Thông báo", "Lỗi hệ thống");
            RequestContext.getCurrentInstance().showMessageInDialog(message);
        }
    }
    
    public void preRenderEditView() {
        this.user = this.userService.find(userId);
        if (this.user != null) {
            List<Group> groupList = this.groupService.findAll();
            for (Group group : this.user.getGroups()) {
                groupList.remove(group);
            }
            this.groupModels = new DualListModel<Group>();
            this.groupModels.setSource(groupList);
            this.groupModels.setTarget(new ArrayList<Group>(this.user.getGroups()));
        } else {
            FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Thông báo", "Người dùng không tồn tại");
            Faces.getContext().addMessage(null, message);
        }
    }
    
    public void updateAction() {
        try {
            user.setGroups(new ArrayList<Group>());
            for(Group group : this.groupModels.getTarget()){
                user.getGroups().add(group);
            }
            User existUser = this.userService.find(user.getId());
            String hashPassword = DigestUtils.md5Hex(user.getPassword());
            if(!existUser.getPassword().equals(hashPassword)){ // changed password
                //  MD5 hash password
                user.setPassword(hashPassword);
            }
            
            this.userService.edit(this.user);
            
            this.reset();
            RequestContext.getCurrentInstance().closeDialog("editDialog");
        } catch (Exception ex) {
            logger.error(ex.getMessage(), ex);
            FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Thông báo", "Lỗi hệ thống");
            RequestContext.getCurrentInstance().showMessageInDialog(message);
        }
    }
    
    public void preNewAction() {
        RequestContext.getCurrentInstance().openDialog("new");
    }
    
    public void preRenderNewView() {
        this.user = new User();
        List<Group> source = groupService.findAll();
        groupModels = new DualListModel<Group>(source, new ArrayList<Group>());
    }
    
    public void saveAction() {
        try {
            user.setGroups(this.groupModels.getTarget());
            String hashPassword = DigestUtils.md5Hex(user.getPassword());
            user.setPassword(hashPassword);
            this.userService.create(this.user);
            
            this.reset();
            RequestContext.getCurrentInstance().closeDialog("newDialog");
        } catch (Exception ex) {
            logger.error(ex.getMessage(), ex);
            FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Thông báo", "Lỗi hệ thống");
            RequestContext.getCurrentInstance().showMessageInDialog(message);
        }
    }
    
    public void preDeleteAction() {
        try {
            if ((this.user == null) && (this.selectedUsers == null || this.selectedUsers.length == 0)) {
                RequestContext.getCurrentInstance().addCallbackParam("invalid", true);
                
                FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, "Thông báo", "Hãy chọn một hoặc nhiều người dùng");
                RequestContext.getCurrentInstance().showMessageInDialog(message);
            }
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Thông báo", "Lỗi hệ thống");
            RequestContext.getCurrentInstance().showMessageInDialog(message);
        }
    }
    
    public void deleteAction() {
        try {
            if(this.user != null) {
                this.userService.remove(user);
            }
            else {
                for(User selectedUser : selectedUsers) {
                    this.userService.remove(selectedUser);
                }
            }
            this.reset();
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Thông báo", "Lỗi hệ thống");
            RequestContext.getCurrentInstance().showMessageInDialog(message);
        }
    }
    
    private void reset() {
        this.user = null;
        this.userId = 0;
        this.selectedUsers = null;
        this.groupModels = null;
    }
}
